package net.wangds.threadpool;

import net.wangds.spring.utils.SpringUtils;
import net.wangds.i18n.utils.I18nUtils;
import net.wangds.log.helper.LogHelper;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@DependsOn({"springUtils"})
@PropertySource("classpath:threadpool.properties")
@Component
public class ThreadPoolConfig implements InitializingBean {


    @Value("${pool.default.core.size}")
    private int mmIntPoolDefaultCoreSize;
    @Value("${pool.default.max.size}")
    private int mmIntPoolDefaultMaxSize;
    @Value("${pool.default.queue.size}")
    private int mmIntPoolDefaultQueueSize;
    @Value("${pool.default.keepalive.second}")
    private int mmIntPoolDefaultKeepAliveSecond;
    @Value("${pool.default.threadname.prefix}")
    private String mmStrPoolDefaultThreadNamePrefix;

    @Value("${pool.default.core.size}")
    private int mmIntPoolMsgCoreSize;
    @Value("${pool.default.max.size}")
    private int mmIntPoolMsgMaxSize;
    @Value("${pool.default.queue.size}")
    private int mmIntPoolMsgQueueSize;
    @Value("${pool.default.keepalive.second}")
    private int mmIntPoolMsgKeepAliveSecond;
    @Value("${pool.default.threadname.prefix}")
    private String mmStrPoolMsgThreadNamePrefix;


    @Bean(name = "pool.default")
    public ThreadPoolTaskExecutor createDefaultPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(mmIntPoolDefaultCoreSize);
        executor.setMaxPoolSize(mmIntPoolDefaultMaxSize);
        executor.setQueueCapacity(mmIntPoolDefaultQueueSize);
        executor.setKeepAliveSeconds(mmIntPoolDefaultKeepAliveSecond);
        executor.setThreadNamePrefix(mmStrPoolDefaultThreadNamePrefix);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        LogHelper.info(SpringUtils.getMessage("msg_mod_common_threadpool_initialized_pool",
                new Object[]{"pool.default", mmIntPoolDefaultCoreSize, mmIntPoolDefaultMaxSize,
                        mmIntPoolDefaultQueueSize, mmIntPoolDefaultKeepAliveSecond,
                        mmStrPoolDefaultThreadNamePrefix}, ""));
        return executor;
    }

    @Bean(name = "pool.msg")
    public ThreadPoolTaskExecutor createMsgPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(mmIntPoolMsgCoreSize);
        executor.setMaxPoolSize(mmIntPoolMsgMaxSize);
        executor.setQueueCapacity(mmIntPoolMsgQueueSize);
        executor.setKeepAliveSeconds(mmIntPoolMsgKeepAliveSecond);
        executor.setThreadNamePrefix(mmStrPoolMsgThreadNamePrefix);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        LogHelper.info(SpringUtils.getMessage("msg_mod_common_threadpool_initialized_pool",
                new Object[]{"pool.msg", mmIntPoolMsgCoreSize, mmIntPoolMsgMaxSize,
                        mmIntPoolMsgQueueSize, mmIntPoolMsgKeepAliveSecond,
                        mmStrPoolMsgThreadNamePrefix}, ""));
        return executor;
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        I18nUtils.addMessagePropertiesFile("messages_mod_common_threadpool");
        LogHelper.info(SpringUtils.getMessage("msg_mod_common_threadpool_loaded"));
    }
}
